

#include<stdio.h>
#include<string.h>

#define SIZE 70

int isLegitSequence(char sequence[]);//getting a sequence of DNA and returning 1 if it's legal, 0 if not 
void getComplementaryStrand(char complementary[],char sequence[]);  //getting an empty array and a strand and filling the complementary
int findSubSequence(char sequence[],char subsequence[]);  //getting a big and small sequences and giving back the last location before the identical place.
int findSubComplementary(char sequence[],char subcomplementary[]);  //getting a sequence and a subcomplementary, returning the findingsubsequence.
void cutSequence(char sequence[],char tocut[]);  //getting a strand and a sequence to cut and giving back the sequence without the one to cut.
void checkDNAList(char data[][SIZE],int rows,char sequence[]); 
void erase_array(char doesnt_matter[SIZE]);//cleaning an array
int checking_main_menu_input(char main_menu_input[]);//getting the main menu array input and getting back the number value
int get_main_menu_value(char main_menu_input[SIZE]);
char complementaryLetter(char letter);//getting a single base and giving back it's complementary
int checking_row_input(char row_input[]);//getting the row array input and getting back the number value
void do_the_middle(int length);//printing row of | between the strand and it's complementary
int checking_line(char line[SIZE],int row);//making sure the row number ain't bigger than the fed 1
void location_location_location(int location, char main[SIZE] ,char subsequence[]);//printing * benieth the subsequence location
int main()
{
	char opp_temp[SIZE], line[SIZE],main_menu_input[SIZE],DNA[SIZE][SIZE],temp[SIZE];
	int moshe=0,i,flag=0,check_1,row=0,menu=0;
	gets(main_menu_input);
	while(menu!=7)
	{
		if(!moshe)
		{
			printf("1.Add DNA Sequence\n"
				"2.Show Complementary DNA Strand\n"
				"3.Find Sequence\n"
				"4.Check For Complementarity\n"
				"5.Cut DNA Sequence\n"
				"6.Search DNA Database\n"
				"7.Exit\n"
				"Enter Your Choice:\n");
		}
		erase_array(main_menu_input);//cleaning an array
		gets(main_menu_input);
		menu=checking_main_menu_input(main_menu_input);//getting the main menu array input and getting back the number value
		if(menu==1)
		{
			printf("\nDNA Strand No.%d\n",row);
			check_1=row;
			erase_array(DNA[row]);//cleaning an array
			while(check_1==row)
			{
				printf("Enter DNA Sequence\n");
				gets(DNA[row]);
				row+=isLegitSequence(DNA[row]);//getting a sequence of DNA and returning 1 if it's legal, 0 if not
				if(!(check_1-row))
					printf("Sequence isn't legal\n\n");
				else
					printf("Sequence number %d is %d bases long\n",row-1,strlen(DNA[row-1]));
				flag=1;
			}
			menu=0;
		}
		if(menu==2&&flag)//done
		{
			printf("Enter DNA Strand Number\n");
			do
			{
				erase_array(line);//cleaning an array
				gets(line);
				if(checking_line(line,row)==-1)//making sure the row number ain't bigger than the fed 1
				{
					printf("Incorrect Strand Number\n"
						"Enter DNA Strand Number\n");
				}
			}
			while(checking_line(line,row)==-1);//making sure the row number ain't bigger than the fed 1
			printf("\n");
			printf("5'-%s-3'\n",DNA[checking_row_input(line)]);//getting the row array input and getting back the number value
			do_the_middle(strlen(DNA[checking_row_input(line)]));//printing row of | between the strand and it's complementary
			erase_array(temp);//cleaning an array
			getComplementaryStrand(temp,DNA[checking_row_input(line)]);//getting an empty array and a strand and filling the complementary
			printf("3'-%s-5'\n",temp);
			menu=0;
		}
		if(menu==3&&flag)
		{
			printf("Enter DNA Strand Number\n\n");
			do
			{
				erase_array(line);//cleaning an array
				gets(line);
				if (checking_line(line,row)==-1)//making sure the row number ain't bigger than the fed 1
					printf("Incorrect Strand Number\n\n"
					"Enter DNA Strand Number\n");
			}
			while(checking_line(line,row)==-1);//making sure the row number ain't bigger than the fed 1
			do
			{
				erase_array(temp);//cleaning an array
				printf("Enter DNA subsequence\n");
				gets(temp);
				if(!isLegitSequence(temp))//getting a sequence of DNA and returning 1 if it's legal, 0 if not
				{
					printf("Sequence isn't legal\n\n"
						"Enter DNA Sequence\n");
				}
			}
			while (!isLegitSequence(temp));//getting a sequence of DNA and returning 1 if it's legal, 0 if not
			if(findSubSequence(DNA[checking_line(line,row)],temp)<0)//getting a big and small sequences and giving back the last location before the identical place.
				printf("No Subsequence\n");
			else
			{
				printf("5'-%s-3'\n",DNA[checking_line(line,row)]);//making sure the row number ain't bigger than the fed 1
				location_location_location(findSubSequence(DNA[checking_line(line,row)],temp),(DNA[checking_line(line,row)]),temp);//printing * benieth the subsequence location
			}
			menu=0;
		}
		if(menu==4&&flag)
		{
			printf("Enter DNA Strand Number\n\n");
			do
			{
				erase_array(line);//cleaning an array
				gets(line);
				if (checking_line(line,row)==-1)//making sure the row number ain't bigger than the fed 1
					printf("Incorrect Strand Number\n\n"
					"Enter DNA Strand Number\n");
			}
			while(checking_line(line,row)==-1);//making sure the row number ain't bigger than the fed 1
			do
			{
				printf("Enter complementary DNA sequence\n");
				erase_array(temp);//cleaning an array
				gets(temp);
				if(!isLegitSequence(temp))//getting a sequence of DNA and returning 1 if it's legal, 0 if not
				{
					printf("Sequence isn't legal\n\n"
						"Enter DNA Sequence\n");
				}				
			}
			while(!isLegitSequence(temp));//getting a sequence of DNA and returning 1 if it's legal, 0 if not

			if(findSubComplementary(DNA[checking_line(line,row)],temp)==-1)//getting a sequence and a subcomplementary, returning the findingsubsequence.
				printf("No Complementary Seqeuence\n");
			else
			{
				printf("5'-%s-3'\n",DNA[checking_line(line,row)]);
				printf("   ");
				for (i=0;i<SIZE;i++)
					if (i>findSubComplementary(DNA[checking_line(line,row)],temp)&&i<=(findSubComplementary(DNA[checking_line(line,row)],temp)+strlen(temp)))
						printf("|");
					else 
						printf(" ");
				printf("\n");
				for(i=0;i<=findSubComplementary(DNA[checking_line(line,row)],temp);i++)//getting a sequence and a subcomplementary, returning the findingsubsequence.
					printf(" ");
				erase_array(opp_temp);//cleaning an array
				for(i=0;temp[i]!='\0';i++)
					opp_temp[strlen(temp)-i-1]=temp[i];
				printf("3'-%s-5'\n",opp_temp);
			}
			menu=0;
		}
		if(menu==5&&flag)
		{
			printf("Enter DNA Strand Number\n\n");
			do
			{
				erase_array(line);//cleaning an array
				gets(line);
				if(checking_line(line,row)==-1)//making sure the row number ain't bigger than the fed 1
					printf("Incorrect Strand Number\n\n"
					"Enter DNA Strand Number\n");
			}
			while(checking_line(line,row)==-1);//making sure the row number ain't bigger than the fed 1
			printf("Enter DNA sequence to cut\n");
			do
			{
				erase_array(temp);//cleaning an array
				gets(temp);
				if(isLegitSequence(temp)==0)//getting a sequence of DNA and returning 1 if it's legal, 0 if not
				{
					printf("Sequence isn't legal\n\n"
						"Enter DNA Sequence\n");
				}				
			}
			while(!isLegitSequence(temp));	//getting a sequence of DNA and returning 1 if it's legal, 0 if not
			cutSequence(DNA[checking_line(line,row)],temp);//getting a strand and a sequence to cut and giving back the sequence without the one to cut.
			printf("5'-%s-3'\n",DNA[checking_line(line,row)]);
			erase_array(temp);	//cleaning an array		
			menu=0;
		}
		if(menu==6&&flag)
		{
			printf("Enter DNA sequence to search\n");
			do
			{
				erase_array(temp);//cleaning an array
				gets(temp);
				if(!isLegitSequence(temp))//getting a sequence of DNA and returning 1 if it's legal, 0 if not
				{
					printf("Sequence isn't legal\n\n"
						"Enter DNA Sequence\n");
				}				
			}
			while(!isLegitSequence(temp));//getting a sequence of DNA and returning 1 if it's legal, 0 if not
			checkDNAList(DNA,row,temp);
			menu=0;
		}
		if(menu==-1)
		{
			printf("\nIncorrect Input\nEnter your choice\n");
			moshe=1;
		}
		if((!flag)&&(menu>0)&&(menu<7))
			printf("No Sequences Entered, Please Add a Sequence\n\n");
		if(menu==0)
			moshe=0;
		if(menu!=7)
			erase_array(temp);//cleaning an array
	}
}

int isLegitSequence(char sequence[])//getting a sequence of DNA and returning 1 if it's legal, 0 if not
{    
	int i;
	for(i=0;sequence[i]!='\0';i++)
		if((sequence[i]!='T')&&(sequence[i]!='C')&&(sequence[i]!='G')&&(sequence[i]!='A')) return 0;
	if(i==0)
		return 0;
	return 1;
}

char complementaryLetter(char letter)//getting a single base and giving back it's complementary
{         
	if(letter=='T') return 'A';
	if(letter=='G') return 'C';
	if(letter=='C') return 'G';
	if(letter=='A') return 'T';
	return '\0';
}

void getComplementaryStrand(char complementary[],char sequence[])//getting an empty array and a strand and filling the complementary
{
	int i=0;
	erase_array(complementary);//cleaning an array
	while(sequence[i]!='\0')
	{
		complementary[i]=(complementaryLetter(sequence[i]));//getting a single base and giving back it's complementary
		i++;
	}
}
int findSubSequence(char sequence[],char subsequence[])//getting a big and small sequences and giving back the last location before the identical place, if doesn't find returning -1.
{
	int a=0, i ,j;
	for (i=0; i<(strlen(sequence)-strlen(subsequence+1));i++)
	{
		a=0;
		for (j=0; j<strlen(subsequence); j++)
		{
			if (sequence[i+j]==subsequence[j])
				a++;
		}
		if (a==strlen(subsequence))
			return (i-1);
	}
	return (-1);
}


int findSubComplementary(char sequence[],char subcomplementary[])//getting a sequence and a subcomplementary, returning the findingsubsequence.
{
	int i;
	char other_way_sub[SIZE];
	erase_array(other_way_sub);//cleaning an array
	for(i=0;i<strlen(subcomplementary);i++)
		other_way_sub[i]=complementaryLetter(subcomplementary[strlen(subcomplementary)-i-1]);//getting other_way_sub the 3-5 complementary so it will fit for finding subsequence. 
	return(findSubSequence(sequence,other_way_sub));//getting a big and small sequences and giving back the last location before the identical place.

}
void cutSequence(char sequence[],char tocut[])//getting a strand and a sequence to cut and giving back the sequence without the one to cut.
{
	int i,j=0,k,p=0;  
	char helper[SIZE];
	for(i=0;i<strlen(sequence);i++)
	{
		if(sequence[i]==tocut[j])
		{
			for(j=0;sequence[i+j]==tocut[j];j++);
			if(j==strlen(tocut))
			{
				erase_array(helper);//cleaning an array
				for(k=0;sequence[k]!='\0';k++)
				{
					if(k<i||k>(i+j-1))
					{
						helper[p]=sequence[k];
						p++;
					}
				}
				erase_array(sequence);//cleaning an array
				for(p=0;helper[p]!='\0';p++)
					sequence[p]=helper[p];
				p=0;
				j=0;

			}
		}
	}
}
void checkDNAList(char data[][SIZE],int rows,char sequence[])
{
	int i,j;
	char upstream[SIZE];
	for(j=0;j<strlen(sequence);j++)
		upstream[j]=sequence[strlen(sequence)-j-1];
	for(i=0; i<rows; i++)
	{
		printf("Person No.%d DNA:\n",i);
		printf("*****************\n");
		if (findSubSequence(data[i],sequence)>=0 ||findSubComplementary(data[i],sequence)>=0)
		{
			if(findSubSequence(data[i],sequence)>=0)
			{
				printf("5'-%s-3'\n",data[i]);
				location_location_location(findSubSequence(data[i],sequence), data[i],sequence);
			}
			if(findSubComplementary(data[i],sequence)>=0)
			{
				printf("5'-%s-3'\n",data[i]);
				location_location_location(findSubComplementary(data[i],sequence),data[i],sequence);//printing * benieth the subsequence location
				for(j=0;j<=findSubComplementary(data[i],sequence);j++)//getting a sequence and a subcomplementary, returning the findingsubsequence.
					printf(" ");
				printf("3'-%s-5'\n",upstream);

			}
		}
		else
			printf("No DNA Match\n\n");
	}
}

void erase_array(char doesnt_matter[SIZE])//cleaning an array
{
	int i;
	for(i=0;i<SIZE;i++)
		doesnt_matter[i]='\0';
}
int checking_main_menu_input(char main_menu_input[])//getting the main menu array input and getting back the number value
{
	int i;
	for(i=0;main_menu_input[i]!='\0';i++)
		if((main_menu_input[i]-'1'<7)&&(main_menu_input[i]-'1'>(-1))&&(strlen(main_menu_input)==1))
			return(main_menu_input[i]-'0');
		else
			return(-1);
	return -1;
}
int checking_row_input(char row_input[])//getting the row array input and getting back the number value
{
	if(strlen(row_input)>2) return -1;
	if((row_input[0]-'0'>9)||(row_input[0]-'0'<0)) return -1;
	if(((row_input[1]-'0'>9)||(row_input[1]-'0'<0))&&strlen(row_input)==2) return -1;
	if(strlen(row_input)==1) return row_input[0]-'0';   
	return ((row_input[0]-'0')*10)+(row_input[1]-'0');
}

void do_the_middle(int length)//printing row of | between the strand and it's complementary
{
	int i=0;
	printf("   ");
	while(i<length)
	{
		printf("|");
		i++;
	}
	printf("\n");
}
int checking_line(char line[SIZE],int row)//making sure the row number ain't bigger than the fed 1
{
	if(checking_row_input(line)>(row))//getting the row array input and getting back the number value
		return -1;
	else
		return checking_row_input(line);//getting the row array input and getting back the number value
}
void location_location_location(int location, char main[SIZE] ,char subsequence[])//printing * benieth the subsequence location
{
	int i;
	printf("   ");
	for (i=0;i<SIZE;i++)
		if (i>location&&i<=(location+strlen(subsequence)))
			printf("*");
		else 
			printf(" ");
	printf("\n");
}